package com.example.demo;

/**
 * @ClassName: PrintAbcDemo_1
 * @Description: 启动三个线程，依次打印A, B, C三个字符。在使用synchronize修饰符的线程下，当前线程使用了wait方法，则直接晋升为重量级锁。
 * 在打印之后，使用notifyAll对同一个管程下的线程全部唤醒在重新竞争。因此以下代码会出现性能问题，可以使用condition(只唤醒一个进程)进行优化
 * @Author:
 * @Date
 */
public class PrintAbcDemo_1 {

    private int singal = 0;
    public synchronized void printA() throws InterruptedException {
        while (singal != 0) {
            wait();
        }
            System.out.println("print_a");
            singal = 1;
            notifyAll();
            Thread.sleep(1000);

    }

    public synchronized void printB() throws InterruptedException {
        while (singal != 1) {
            wait();
        }
            System.out.println("print_B|");
            singal = 2;
            notifyAll();
            Thread.sleep(1000);

    }

    public synchronized void printC() throws InterruptedException {
        while (singal != 2) {
            wait();
        }
            System.out.println("print_c");
            singal = 0;
            notifyAll();
            Thread.sleep(1000);

    }

    public static void main(String[] args) {
        PrintAbcDemo_1 print1 = new PrintAbcDemo_1();
        // 分别启动三个线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        print1.printA();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        print1.printB();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        print1.printC();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        Thread.yield();
    }
}
